package cn.jdemo.juc.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @see Thread#yield() 让出cpu，然后大家一起重新抢，该线程如果再次获取，则继续执行
 * @date 2020/12/7
 *
 * 线程原子性：线程执行原子性
 *
 * 前提条件:不使用lock和sychronized
 *         volatile关键字无法保证线程的原子性操作
 *
 * 解决方案:使用juc中的原子类解决,其操作具有原子性 [CAS(compare and swap)即比较并交换]
 */
public class YieldDemo02 {
    public static void main(String[] args) throws InterruptedException {
        // test01();
        test02();
    }

    /**
     * 执行结果:
     * Thread-1 : 开始: 5001
     * Thread-2 : 开始: 10001
     * Thread-6 : 开始: 15001
     * Thread-5 : 开始: 20001
     * Thread-9 : 开始: 25001
     * Thread-0 : 开始: 30001
     * Thread-4 : 开始: 35919
     * Thread-8 : 开始: 40001
     * Thread-3 : 开始: 45001
     * Thread-7 : 开始: 50001
     *
     * @throws InterruptedException
     */
    public static void test01() throws InterruptedException {
        AtomicInteger atomicInteger = new AtomicInteger(1);
        for (int i = 1; i <= 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 5000; j++) {
                    atomicInteger.getAndIncrement();
                }
                System.out.println(Thread.currentThread().getName()+" : 开始: "+atomicInteger.get());
            }).start();
        }

        //java程序中最少有2条线程在执行（main线程和GC垃圾回收线程）
        //如果活跃的线程数大于2，说明除了main线程和GC线程外还有线程在工作，则进行礼让，即不执行while循环以下的程序
        if (Thread.activeCount()>2){
            Thread.yield();
        }
    }

    /**
     * 计算结果
     * Thread-1 : 开始: 5001
     * Thread-2 : 开始: 12021
     * Thread-9 : 开始: 20001
     * Thread-7 : 开始: 25001
     * Thread-5 : 开始: 15001
     * Thread-3 : 开始: 30001
     * Thread-0 : 开始: 35001
     * Thread-4 : 开始: 40001
     * Thread-8 : 开始: 45001
     * Thread-6 : 开始: 50001
     */
    public static void test02() throws InterruptedException {
        AtomicInteger atomicInteger = new AtomicInteger(1);
        for (int i = 1; i <= 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 5000; j++) {
                    atomicInteger.getAndIncrement();
                }
                System.out.println(Thread.currentThread().getName()+" : 开始: "+atomicInteger.get());
            }).start();
        }
    }
}
